/*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.

package javax.clear.sun.reflect.misc;

import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.security.*;
import java.util.*;

// Referenced classes of package sun.reflect.misc:
//            ReflectUtil

public final class MethodUtil extends SecureClassLoader
{
    private static class Signature
    {

        public boolean equals(Object obj)
        {
            if(this == obj)
                return true;
            Signature signature = (Signature)obj;
            if(!methodName.equals(signature.methodName))
                return false;
            if(argClasses.length != signature.argClasses.length)
                return false;
            for(int i = 0; i < argClasses.length; i++)
                if(argClasses[i] != signature.argClasses[i])
                    return false;

            return true;
        }

        public int hashCode()
        {
            if(hashCode == 0)
            {
                int i = 17;
                i = 37 * i + methodName.hashCode();
                if(argClasses != null)
                {
                    for(int j = 0; j < argClasses.length; j++)
                        i = 37 * i + (argClasses[j] != null ? argClasses[j].hashCode() : 0);

                }
                hashCode = i;
            }
            return hashCode;
        }

        private String methodName;
        private Class argClasses[];
        private volatile int hashCode;

        Signature(Method method)
        {
            hashCode = 0;
            methodName = method.getName();
            argClasses = method.getParameterTypes();
        }
    }


    private MethodUtil()
    {
    }

    public static Method getMethod(Class class1, String s, Class aclass[])
        throws NoSuchMethodException
    {
        ReflectUtil.checkPackageAccess(class1);
        return class1.getMethod(s, aclass);
    }

    public static Method[] getMethods(Class class1)
    {
        ReflectUtil.checkPackageAccess(class1);
        return class1.getMethods();
    }

    public static Method[] getPublicMethods(Class class1)
    {
        if(System.getSecurityManager() == null)
            return class1.getMethods();
        HashMap hashmap = new HashMap();
        do
        {
            if(class1 == null)
                break;
            boolean flag = getInternalPublicMethods(class1, hashmap);
            if(flag)
                break;
            getInterfaceMethods(class1, hashmap);
            class1 = class1.getSuperclass();
        } while(true);
        Collection collection = hashmap.values();
        return (Method[])(Method[])collection.toArray(new Method[collection.size()]);
    }

    private static void getInterfaceMethods(Class class1, Map map)
    {
        Class aclass[] = class1.getInterfaces();
        for(int i = 0; i < aclass.length; i++)
        {
            Class class2 = aclass[i];
            boolean flag = getInternalPublicMethods(class2, map);
            if(!flag)
                getInterfaceMethods(class2, map);
        }

    }

    private static boolean getInternalPublicMethods(Class class1, Map map)
    {
        Method amethod[];
        amethod = null;
        try
        {
            if(!Modifier.isPublic(class1.getModifiers()))
                return false;
        }
        catch(SecurityException securityexception)
        {
            return false;
        }
        if(!ReflectUtil.isPackageAccessible(class1))
            return false;
        amethod = class1.getMethods();
        boolean flag = true;
        int i = 0;
        do
        {
            if(i >= amethod.length)
                break;
            Class class2 = amethod[i].getDeclaringClass();
            if(!Modifier.isPublic(class2.getModifiers()))
            {
                flag = false;
                break;
            }
            i++;
        } while(true);
        if(flag)
        {
            for(int j = 0; j < amethod.length; j++)
                addMethod(map, amethod[j]);

        } else
        {
            for(int k = 0; k < amethod.length; k++)
            {
                Class class3 = amethod[k].getDeclaringClass();
                if(class1.equals(class3))
                    addMethod(map, amethod[k]);
            }

        }
        return flag;
    }

    private static void addMethod(Map map, Method method)
    {
        Signature signature = new Signature(method);
        if(!map.containsKey(signature))
            map.put(signature, method);
        else
        if(!method.getDeclaringClass().isInterface())
        {
            Method method1 = (Method)map.get(signature);
            if(method1.getDeclaringClass().isInterface())
                map.put(signature, method);
        }
    }

    public static Object invoke(Method method, Object obj, Object aobj[])
        throws InvocationTargetException, IllegalAccessException
    {
        try
        {
            return bounce.invoke(null, new Object[] {
                method, obj, aobj
            });
        }
        catch(InvocationTargetException invocationtargetexception)
        {
            Throwable throwable = invocationtargetexception.getCause();
            if(throwable instanceof InvocationTargetException)
                throw (InvocationTargetException)throwable;
            if(throwable instanceof IllegalAccessException)
                throw (IllegalAccessException)throwable;
            if(throwable instanceof RuntimeException)
                throw (RuntimeException)throwable;
            if(throwable instanceof Error)
                throw (Error)throwable;
            else
                throw new Error("Unexpected invocation error", throwable);
        }
        catch(IllegalAccessException illegalaccessexception)
        {
            throw new Error("Unexpected invocation error", illegalaccessexception);
        }
    }

    private static Method getTrampoline()
    {
        Method method = null;
        try
        {
            method = (Method)AccessController.doPrivileged(new PrivilegedExceptionAction() {

                public Object run()
                    throws Exception
                {
                    Class class1 = MethodUtil.getTrampolineClass();
                    Class aclass[] = {
                        java.lang.reflect.Method.class, java.lang.Object.class
                    };
                    Method method1 = class1.getDeclaredMethod("invoke", aclass);
                    method1.setAccessible(true);
                    return method1;
                }

            }
);
        }
        catch(Exception exception)
        {
            throw new InternalError("bouncer cannot be found");
        }
        return method;
    }

    protected synchronized Class loadClass(String s, boolean flag)
        throws ClassNotFoundException
    {
        ReflectUtil.checkPackageAccess(s);
        Class class1 = findLoadedClass(s);
        if(class1 == null)
        {
            try
            {
                class1 = findClass(s);
            }
            catch(ClassNotFoundException classnotfoundexception) { }
            if(class1 == null)
                class1 = getParent().loadClass(s);
        }
        if(flag)
            resolveClass(class1);
        return class1;
    }

    protected Class findClass(String s)
        throws ClassNotFoundException
    {
        if(!s.startsWith(MISC_PKG))
            throw new ClassNotFoundException(s);
        String s1 = s.replace('.', '/').concat(".class");
        URL url = getResource(s1);
        if(url != null)
            try
            {
                return defineClass(s, url);
            }
            catch(IOException ioexception)
            {
                throw new ClassNotFoundException(s, ioexception);
            }
        else
            throw new ClassNotFoundException(s);
    }

    private Class defineClass(String s, URL url)
        throws IOException
    {
        byte abyte0[] = getBytes(url);
        CodeSource codesource = new CodeSource(null, (java.security.cert.Certificate[])null);
        if(!s.equals(TRAMPOLINE))
            throw new IOException((new StringBuilder()).append("MethodUtil: bad name ").append(s).toString());
        else
            return defineClass(s, abyte0, 0, abyte0.length, codesource);
    }

    private static byte[] getBytes(URL url)
        throws IOException
    {
        int i;
        BufferedInputStream bufferedinputstream;
        URLConnection urlconnection = url.openConnection();
        if(urlconnection instanceof HttpURLConnection)
        {
            HttpURLConnection httpurlconnection = (HttpURLConnection)urlconnection;
            int k = httpurlconnection.getResponseCode();
            if(k >= 400)
                throw new IOException("open HTTP connection failed.");
        }
        i = urlconnection.getContentLength();
        bufferedinputstream = new BufferedInputStream(urlconnection.getInputStream());
        byte abyte0[];
        if(i != -1)
        {
            abyte0 = new byte[i];
            int l;
            for(; i > 0; i -= l)
            {
                l = bufferedinputstream.read(abyte0, abyte0.length - i, i);
                if(l == -1)
                    throw new IOException("unexpected EOF");
            }

        } else
        {
            abyte0 = new byte[8192];
            int i1 = 0;
            do
            {
                int j;
                if((j = bufferedinputstream.read(abyte0, i1, abyte0.length - i1)) == -1)
                    break;
                i1 += j;
                if(i1 >= abyte0.length)
                {
                    byte abyte1[] = new byte[i1 * 2];
                    System.arraycopy(abyte0, 0, abyte1, 0, i1);
                    abyte0 = abyte1;
                }
            } while(true);
            if(i1 != abyte0.length)
            {
                byte abyte2[] = new byte[i1];
                System.arraycopy(abyte0, 0, abyte2, 0, i1);
                abyte0 = abyte2;
            }
        }
        bufferedinputstream.close();
        bufferedinputstream.close();
        return abyte0;
    }

    protected PermissionCollection getPermissions(CodeSource codesource)
    {
        PermissionCollection permissioncollection = super.getPermissions(codesource);
        permissioncollection.add(new AllPermission());
        return permissioncollection;
    }

    private static Class getTrampolineClass()
    {
        try
        {
            return Class.forName(TRAMPOLINE, true, new MethodUtil());
        }
        catch(ClassNotFoundException classnotfoundexception)
        {
            return null;
        }
    }

    private static String MISC_PKG;
    private static String TRAMPOLINE;
    private static Method bounce = getTrampoline();

    static 
    {
        MISC_PKG = "sun.reflect.misc.";
        TRAMPOLINE = (new StringBuilder()).append(MISC_PKG).append("Trampoline").toString();
    }

}
